/**
   * @输入层
   * 设定输入数据的形状为NHWC，即[批次，高度，宽度，通道数]
   * 固定输入的数据格式为：1215高，1215宽，3通道
   */
const inputLayer = tf.input({
  name: "input",
  // 输入空间的形状，不需要加batchSize的null
  shape: [729, 729, 3],
  // batchSize维持默认（32）即可
})
/**
 * @卷积层
 */
// 卷积层1。以inputLayer层为输入
const conv2dLayer1 = tf.layers.conv2d({
  name: "cnn-conv2d-1",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(inputLayer)
// 池化层-最大1。以conv2dLayer1层为输入
const maxPool2dLayer1 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-1",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer1)
// 卷积层2。以maxPool2dLayer1层为输入
const conv2dLayer2 = tf.layers.conv2d({
  name: "cnn-conv2d-2",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(maxPool2dLayer1)
// 池化层-最大2。以conv2dLayer2b层为输入
const maxPool2dLayer2 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-2",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer2)
// 卷积层3。以maxPool2dLayer2层为输入
const conv2dLayer3 = tf.layers.conv2d({
  name: "cnn-conv2d-3",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(maxPool2dLayer2)
// 池化层-最大3。以conv2dLayer3层为输入
const maxPool2dLayer3 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-3",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer3)
// 卷积层4。以maxPool2dLayer3层为输入
const conv2dLayer4 = tf.layers.conv2d({
  name: "cnn-conv2d-4",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(maxPool2dLayer3)
// 池化层-最大4。以conv2dLayer4b层为输入
const maxPool2dLayer4 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-4",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer4)
// 卷积层5。以maxPool2dLayer4层为输入
const conv2dLayer5 = tf.layers.conv2d({
  name: "cnn-conv2d-5",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(maxPool2dLayer4)
// 池化层-最大5。以conv2dLayer5层为输入
const maxPool2dLayer5 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-5",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer5)
// 卷积层6。以maxPool2dLayer5层为输入
const conv2dLayer6 = tf.layers.conv2d({
  name: "cnn-conv2d-6",
  // 滤波器数量，即输出的最后一层channels层增加倍数
  filters: 64,
  // 卷积核尺寸
  kernelSize: [3, 3],
  // 卷积步长
  strides: [1, 1],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
  // 不启用偏差
  useBias: false,
  // 激活函数
  activation: "softsign",
}).apply(maxPool2dLayer5)
// 池化层-最大6。以conv2dLayer5b层为输入
const maxPool2dLayer6 = tf.layers.maxPooling2d({
  name: "cnn-max-pool1d-6",
  // 池化尺寸
  poolSize: [3, 3],
  // 池化步长
  strides: [3, 3],
  // 边缘处理方法，valid为不添加填充，same为填充
  padding: "same",
}).apply(conv2dLayer6)
// 扁平化层。以maxPool2dLayer6层为输入
const flattenLayer = tf.layers.flatten({
  name: "cnn-flatten",
}).apply(maxPool2dLayer6)
// 全连接层。以flattenLayer层为输入
const denseLayer1 = tf.layers.dense({
  name: "cnn-dense-1",
  // 输出空间的维度
  units: 32,
  // 启用偏差
  useBias: true,
  // 激活函数
  activation: "softsign",
}).apply(flattenLayer)
// dropout层。以denseLayer1层为输入
const dropoutLayer = tf.layers.dropout({
  name: "cnn-dropout",
  // 随机“丢弃”一些前一层传来的神经元，以防过拟合
  rate: 0.5,
  // 掩码，以确保形状，一般不需要
  noiseShape: undefined,
  // 种子，相同的种子可以确保训练随机数能重复
  seed: 1,
}).apply(denseLayer1)
// 全连接层。以dropoutLayer层为输入
const denseLayer2 = tf.layers.dense({
  name: "cnn-dense-2",
  // 输出空间的维度
  units: 1,
  // 启用偏差
  useBias: true,
  // 激活函数
  activation: "relu",
}).apply(dropoutLayer)
/**
 * @建立模型
 */
const model = tf.model({
  name: "cnn-model",
  // 输入层
  inputs: inputLayer,
  // 输出层
  outputs: denseLayer2
})